﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using HeritageAcademy.Models.DataModels;
using HeritageAcademy.Models.Loaders;
using HeritageAcademy.Models.ViewModels;
using HeritageAcademy.Shared.Languages;

namespace HeritageAcademy.Library.Controls
{
    /// <summary>
    /// Test board
    /// </summary>
    public partial class TestBoard
    {
        #region Parameters
        
        // Models
        private TestWizardViewModel _tvm;
        private UsersConfigLoader _usersConfigLoader;
        private readonly Russian _russian;
        private readonly Shared.Duration _duration;
        
        // Constants
        private readonly int averageOneTestPageDuration = Convert.ToInt32(Shared.Properties.Resources.Test_AverageDuration);
        private const double ledderStepWidth = 18;
        private const double ledderStepHeight = 6;
        
        #endregion

        #region Ctor
        
        public TestBoard()
        {
            InitializeComponent();
            _russian = new Russian();
            _duration = new Shared.Duration();
            btnStartTest.Click += btnStartTest_Click;
        }

        #endregion

        #region Event Handlers
        void btnStartTest_Click(object sender, RoutedEventArgs e)
        {
            Navigator.Current.ShowTestWizard(_tvm);
        }
        #endregion

        #region Methods
        
        public void InitializeTestsList()
        {
            _usersConfigLoader = new UsersConfigLoader(new Users());
            _tvm = (TestWizardViewModel)DataContext;
            UpdateDuration(_duration.Calculate(_tvm.PageCount, averageOneTestPageDuration));
            UpdateStat();
            _tvm.PropertyChanged += _tvm_PropertyChanged;
        }

        void _tvm_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "SelectedTestTitle")
            {
                UpdateDuration(_duration.Calculate(_tvm.PageCount, averageOneTestPageDuration));
                UpdateStat();
            }
        }

        #region Duration

        private void UpdateDuration(Dictionary<string, int> duration)
        {
            int h = duration["hours"];
            int m = duration["minutes"];

            if (h == 0)
            {
                tbH.Visibility = Visibility.Collapsed;
                tbHCaption.Visibility = Visibility.Collapsed;
            }
            else
            {
                tbH.Visibility = Visibility.Visible;
                tbHCaption.Visibility = Visibility.Visible;
                tbH.Text = h.ToString();
                tbHCaption.Text = _russian.Grammar(Russian.Word.Hour, h);
            }
            tbM.Text = m.ToString();
            tbMCaption.Text = _russian.Grammar(Russian.Word.Minute, m);
        }

        #endregion

        #region Ledder
        private void BuildTestLadder(int totalQty, int firstLevelQty, int secondLevelQty, int thirdLevelQty)
        {
            int level2 = firstLevelQty + secondLevelQty;
            int level3 = level2 + thirdLevelQty;

            plbLedder.IsHitTestVisible = false;
            plbLedder.Items.Clear();

            for (int i = 1; i <= totalQty; i++)
            {
                if (i >= 1 & i <= firstLevelQty)
                {
                    plbLedder.Items.Add(LedderStep("1", 0.87));
                }
                else if (i > firstLevelQty & i <= level2)
                {
                    plbLedder.Items.Add(LedderStep("2", 0.55));
                }
                else if (i > level2 & i <= level3)
                {
                    plbLedder.Items.Add(LedderStep("3", 0.37));
                }
                else if (i > level3 & i <= totalQty)
                {
                    plbLedder.Items.Add(LedderStep("4", 0.11));
                }
            }
        }

        private static Canvas LedderStep(string level, double progress)
        {
            var ledderStepBrush = new SolidColorBrush();
            switch (level)
            {
                case "1":
                    ledderStepBrush.Color = Colors.Brown;
                    break;
                case "2":
                    ledderStepBrush.Color = Colors.Blue;
                    break;
                case "3":
                    ledderStepBrush.Color = Colors.Green;
                    break;
                case "4":
                    ledderStepBrush.Color = Colors.Red;
                    break;
            }

            var container = new Canvas {Width = ledderStepWidth, Height = ledderStepHeight};

            var stepFill = new Rectangle
                               {
                                   RadiusX = 2.0,
                                   RadiusY = 2.0,
                                   Width = progress*ledderStepWidth,
                                   Height = ledderStepHeight,
                                   Fill = ledderStepBrush,
                                   HorizontalAlignment = HorizontalAlignment.Left,
                                   VerticalAlignment = VerticalAlignment.Center,
                                   SnapsToDevicePixels = true
                               };

            var stepBorder = new Rectangle
                                 {
                                     RadiusX = 2.0,
                                     RadiusY = 2.0,
                                     Width = ledderStepWidth,
                                     Height = ledderStepHeight,
                                     Stroke = ledderStepBrush,
                                     VerticalAlignment = VerticalAlignment.Center,
                                     SnapsToDevicePixels = true
                                 };

            container.Children.Add(stepBorder);
            container.Children.Add(stepFill);
            return container;
        }

        private TextBlock LedderStepText(string txt)
        {
            var n = new TextBlock
                        {
                            Text = txt,
                            Margin = new Thickness(0, 0, 8, 0),
                            VerticalAlignment = VerticalAlignment.Center
                        };
            return n;
        }
        #endregion

        private void UpdateStat()
        {
            var rvm = new ResultsViewModel(_usersConfigLoader.ActiveUser.Id, _tvm.CurrentTest.Model.Id);
            rvm.InitializeResults(_tvm.CurrentTest.Source);
            rvm.GetTestResults();
            grdStat.DataContext = rvm;
            UpdateStatLayout();
        }

        private void UpdateStatLayout()
        {
            var nall = ((ResultsViewModel) grdStat.DataContext).TotalNumberOfAnswers;
            var nwrg = ((ResultsViewModel) grdStat.DataContext).NumberOfWrongAnswers;
            if (nall == 0)
            {
                spAns1.Visibility = Visibility.Collapsed;
                spAns2.Visibility = Visibility.Collapsed;
                tbAnsWrongNone.Visibility = Visibility.Collapsed;
                tbAnsWrongAll.Visibility = Visibility.Collapsed;
                tbAnsNone.Visibility = Visibility.Visible;
            }
            else
            {
                tbAnsNone.Visibility = Visibility.Collapsed;
                spAns1.Visibility = Visibility.Visible;
                tbAnsQtyAll.Text = nall.ToString();
                if (nwrg == 0)
                {
                    spAns2.Visibility = Visibility.Collapsed;
                    tbAnsWrongAll.Visibility = Visibility.Collapsed;
                    tbAnsWrongNone.Visibility = Visibility.Visible;
                }
                else if (nwrg == nall)
                {
                    tbAnsQtyAllCaption.Text = _russian.Grammar(Russian.Word.Time, nall);
                    spAns2.Visibility = Visibility.Collapsed;
                    tbAnsWrongNone.Visibility = Visibility.Collapsed;
                    tbAnsWrongAll.Visibility = Visibility.Visible;
                }
                else
                {
                    tbAnsWrongAll.Visibility = Visibility.Collapsed;
                    tbAnsWrongNone.Visibility = Visibility.Collapsed;
                    spAns2.Visibility = Visibility.Visible;
                    tbAnsQtyWrong.Text = nwrg.ToString();
                    tbAnsQtyAllCaption.Text = _russian.Grammar(Russian.Word.Time, nall);
                    tbAnsQtyWrongCaption.Text = _russian.Grammar(Russian.Word.Time, nwrg);
                    tbAnsNone.Visibility = Visibility.Collapsed;
                    spAns1.Visibility = Visibility.Visible;
                    spAns2.Visibility = Visibility.Visible;
                }
            }
        }

        #endregion
    }
}
